﻿using System.Collections.Generic;
using DR.Repository.Abstract;
using NHibernate;
using NHibernate.Criterion;

namespace DR.Repository.Concrete.NHibernate
{
    public class HRepository<E, K> : IRepository<E, K>
    {

        protected ISession CreateSession()
        {
            return HSessionFactoryUtil.OpenSession();
        }

        public E SelectByID(K id)
        {
            using (ISession session = CreateSession())
            {
                return session.Get<E>(id);
            }
        }

        public IList<E> SelectAll()
        {
            using (ISession session = CreateSession())
            {
                return session.CreateCriteria(typeof(E)).List<E>();
            }
        }

        public IList<E> SelectAll(int startIndex, int maxSize)
        {
            using (ISession session = CreateSession())
            {
                return session.CreateCriteria(typeof(E)).SetFirstResult(startIndex).SetMaxResults(maxSize).List<E>();
            }
        }

        public E Update(E entity)
        {
            using (ISession session = CreateSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Update(entity);
                    session.Flush();
                    return entity;
                }
            }
        }

        public E Insert(E entity)
        {
            using (ISession session = CreateSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(entity);
                    session.Flush();
                    return entity;
                }
            }
        }

        public void Delete(K id)
        {
            using (ISession session = CreateSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    E entity = session.Load<E>(id);
                    session.Delete(entity);
                    session.Flush();
                }
            }
        }

        public int GetCount()
        {

            using (ISession session = CreateSession())
            {
                return session.CreateCriteria(typeof(E)).SetProjection(Projections.RowCount()).UniqueResult<int>();
            }
        }
    }
}
